package com.rslai.base.tool.servertest.transport.command;

import com.rslai.base.tool.autotest.mock.util.JSON;
import com.rslai.base.tool.servertest.model.KeyValueStore;
import com.rslai.base.tool.servertest.objectfactory.BeanUtils;
import com.rslai.base.tool.servertest.response.Response;
import com.rslai.base.tool.servertest.transport.dubbo.DubboServiceFactory;
import com.rslai.base.tool.servertest.util.ReflectionUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DubboExecuteCommand extends ExecuteCommand {
    private static final Logger logger = LoggerFactory.getLogger(DubboExecuteCommand.class);
    private final com.rslai.base.tool.servertest.transport.model.ServiceDesc serviceDesc;

    public DubboExecuteCommand(String id, com.rslai.base.tool.servertest.transport.model.ServiceDesc serviceDesc, String desc) {
        super(id, desc);
        this.serviceDesc = serviceDesc;
    }

    public Response execute(List<KeyValueStore> params) {
        Response response = new Response();
        try {
            Object service = DubboServiceFactory.getRpcService(this.serviceDesc);
            Method executeMethod = ReflectionUtils.getMethod(this.serviceDesc.getMethod(), this.serviceDesc.getServiceClass());
            Object[] parameters = BeanUtils.getParameters(params, executeMethod.getGenericParameterTypes());
            if (logger.isInfoEnabled()) {
                logger.info("Rpc request start: params={}", new Object[]{JSON.toJSONString(parameters)});
            }
            Object result = executeMethod.invoke(service, parameters);
            response.setBody(result);
        } catch (InvocationTargetException ite) {
            logger.error("call rpc error", ite.getTargetException());
            response.setException(ite.getTargetException());
        } catch (IllegalAccessException e) {
            throw new RuntimeException("illegal access", e);
        } catch (Exception e) {
            logger.error("call rpc error", e);
            response.setException(e);
        }
        return response;
    }

    public String toReport() {
        return String.format("调用位于%s的Dubbo服务%s.%s, version=%s", new Object[]{this.serviceDesc.getUrl(), this.serviceDesc.getClazz(), this.serviceDesc.getMethod(), this.serviceDesc.getVersion()});
    }

    public com.rslai.base.tool.servertest.model.ServiceDesc desc() {
        return new com.rslai.base.tool.servertest.model.ServiceDesc(this.id, String.format("%s.%s", new Object[]{this.serviceDesc.getClazz(), this.serviceDesc.getMethod()}), this.desc);
    }
}

